package com.yale.elasticsearch.service.aggregation;


import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.aggregations.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;


/**
 * 聚合 Metric
 */
@Slf4j
@Service
public class AggrMetricService {

    @Resource
    private ElasticsearchClient elasticsearchClient;

    /**
     * stats 统计员工总数、工资最高值、工资最低值、工资平均工资、工资总和
     */
    public Object aggregationStats() {
        String responseResult = "";
        try {
            // 设置聚合条件
            StatsAggregation statsAgg = StatsAggregation.of(s -> s.field("salary"));

            // 创建聚合查询请求
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("salary_stats", a -> a.stats(statsAgg))
            );

            // 执行请求
            SearchResponse<Void> response = elasticsearchClient.search(searchRequest, Void.class);

            // 获取响应中的聚合信息
            Aggregate aggregate = response.aggregations().get("salary_stats");

            // 输出内容
            if (aggregate != null && aggregate._kind() == Aggregate.Kind.Stats) {
                StatsAggregate stats = (StatsAggregate) aggregate._get();

                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                System.out.printf("count：%d%n", stats.count());
                System.out.printf("avg：%.2f%n", stats.avg());
                System.out.printf("max：%.2f%n", stats.max());
                System.out.printf("min：%.2f%n", stats.min());
                System.out.printf("sum：%.2f%n", stats.sum());
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationStats() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            AggregationBuilder aggr = AggregationBuilders.stats("salary_stats").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            // 设置查询结果不返回，只返回聚合结果
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 Stats 对象
//                ParsedStats aggregation = aggregations.get("salary_stats");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                log.info("count：{}", aggregation.getCount());
//                log.info("avg：{}", aggregation.getAvg());
//                log.info("max：{}", aggregation.getMax());
//                log.info("min：{}", aggregation.getMin());
//                log.info("sum：{}", aggregation.getSum());
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

    /**
     * min 统计员工工资最低值
     */
    public Object aggregationMin() {
        String responseResult = "";
        try {
            // 设置聚合条件
            MinAggregation minAgg = MinAggregation.of(m -> m.field("salary"));

            // 创建聚合查询请求
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("salary_min", a -> a.min(minAgg))
            );

            // 执行请求
            SearchResponse<Void> response = elasticsearchClient.search(searchRequest, Void.class);

            // 获取响应中的聚合信息
            Aggregate aggregate = response.aggregations().get("salary_min");

            // 输出内容
            if (aggregate != null && aggregate.isMin()) {
                MinAggregate min = (MinAggregate) aggregate._get();

                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                System.out.printf("min：%.2f%n", min.value());
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationMin() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            AggregationBuilder aggr = AggregationBuilders.min("salary_min").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 Min 对象
//                ParsedMin aggregation = aggregations.get("salary_min");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                log.info("min：{}", aggregation.getValue());
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

    /**
     * max 统计员工工资最高值
     */
    public Object aggregationMax() {
        String responseResult = "";
        try {
            MaxAggregation maxAgg = MaxAggregation.of(m -> m.field("salary"));

            // 创建聚合查询请求
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("salary_max", a -> a.max(maxAgg))
            );



            // 执行请求
            SearchResponse<Void> response = elasticsearchClient.search(searchRequest, Void.class);

            // 获取响应中的聚合信息
            Aggregate aggregate = response.aggregations().get("salary_max");

            // 输出内容
            if (aggregate != null && aggregate.isMax()) {
                MinAggregate max = (MinAggregate) aggregate._get();

                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                System.out.printf("min：%.2f%n", max.value());
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationMax() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            AggregationBuilder aggr = AggregationBuilders.max("salary_max").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 Max 对象
//                ParsedMax aggregation = aggregations.get("salary_max");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                log.info("max：{}", aggregation.getValue());
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

    /**
     * avg 统计员工工资平均值
     */
    public Object aggregationAvg() {
        String responseResult = "";
        try {
            // 设置聚合条件
//            AvgAggregate avgAgg = AvgAggregate.of(a -> a.field("salary"));

            // 创建聚合查询请求
//            SearchRequest searchRequest = SearchRequest.of(s -> s
//                    .index("mydlq-user")
//                    .size(0) // 不返回文档，只返回聚合结果
//                    .aggregations("salary_avg", a -> a.avg(avgAgg))
//            );
            // 设置聚合条件
            AverageAggregation avgAgg = AverageAggregation.of(a -> a.field("salary"));

            // 创建聚合查询请求
            SearchRequest salaryAvg = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("salary_avg", a -> a.avg(avgAgg))
            );

            // 执行请求
            SearchResponse<JsonData> response = elasticsearchClient.search(salaryAvg, JsonData.class);

            // 获取响应中的聚合信息
            AvgAggregate avgAggregate = response.aggregations().get("salary_avg").avg();

            // 输出内容
            if (avgAggregate != null) {
                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                System.out.printf("avg：%.2f%n", avgAggregate.value());
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationAvg() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            AggregationBuilder aggr = AggregationBuilders.avg("salary_avg").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 Avg 对象
//                ParsedAvg aggregation = aggregations.get("salary_avg");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                log.info("avg：{}", aggregation.getValue());
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

    /**
     * sum 统计员工工资总值
     */
    public Object aggregationSum() {
        String responseResult = "";
        try {

            // 设置聚合条件
            SumAggregation avgAgg = SumAggregation.of(a -> a.field("salary"));

            // 创建聚合查询请求
            SearchRequest salaryAvg = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("salary_sum", a -> a.sum(avgAgg))
            );

            // 执行请求
            SearchResponse<JsonData> response = elasticsearchClient.search(salaryAvg, JsonData.class);

            // 获取响应中的聚合信息
            AvgAggregate avgAggregate = response.aggregations().get("salary_sum").avg();


            // 输出内容
            if (avgAggregate != null) {
                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                System.out.printf("avg：%.2f%n", avgAggregate.value());
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationSum() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            SumAggregationBuilder aggr = AggregationBuilders.sum("salary_sum").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 Sum 对象
//                ParsedSum aggregation = aggregations.get("salary_sum");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                log.info("sum：{}", String.valueOf((aggregation.getValue())));
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

    /**
     * count 统计员工总数
     */
    public Object aggregationCount() {
        String responseResult = "";
        try {
            // 设置聚合条件
            ValueCountAggregation valueCountAgg = ValueCountAggregation.of(v -> v
                    .field("salary")
            );

            // 创建聚合查询请求

            SearchRequest valueCount = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("employee_count", a -> a.valueCount(valueCountAgg))
            );
            // 执行请求
            SearchResponse<JsonData> response = elasticsearchClient.search(valueCount, JsonData.class);

            // 获取响应中的聚合信息
            ValueCountAggregate countAggregate = response.aggregations().get("employee_count").valueCount();

            // 输出内容
            if (countAggregate != null) {
                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                System.out.printf("count：%.0f%n", countAggregate.value());
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationCount() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            AggregationBuilder aggr = AggregationBuilders.count("employee_count").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 ValueCount 对象
//                ParsedValueCount aggregation = aggregations.get("employee_count");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                log.info("count：{}", aggregation.getValue());
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

    /**
     * percentiles 统计员工工资百分位
     */
    public Object aggregationPercentiles() {
        String responseResult = "";
        try {
            // 设置聚合条件
            PercentilesAggregation percentilesAgg = PercentilesAggregation.of(p -> p
                    .field("salary")
                    .percents(50.0, 90.0, 95.0) // 设置你想要计算的百分位数
            );

            // 创建聚合查询请求
            SearchRequest valueCount = SearchRequest.of(s -> s
                    .index("mydlq-user")
                    .size(0) // 不返回文档，只返回聚合结果
                    .aggregations("salary_percentiles", a -> a.percentiles(percentilesAgg))
            );

            // 执行请求
            SearchResponse<JsonData> response = elasticsearchClient.search(valueCount, JsonData.class);

            // 获取响应中的聚合信息
//           ParentAggregate percentilesAggregate = (ParentAggregate) response.aggregations().get("salary_percentiles")._get();
            Aggregate aggregate = response.aggregations().get("salary_percentiles");

            // 输出内容
            if (aggregate != null) {
                System.out.println("-------------------------------------------");
                System.out.println("聚合信息:");
                // TODO: 2024/8/2

//                for (Map.Entry<Double, Double> entry : aggregate.value().entrySet()) {
//                    System.out.printf("百分位：%.1f：%f%n", entry.getKey(), entry.getValue());
//                }
                System.out.println("-------------------------------------------");

                responseResult = response.toString();
            }
        } catch (IOException e) {
            System.err.println("Error executing search request: " + e.getMessage());
        }
        return responseResult;
    }
//    public Object aggregationPercentiles() {
//        String responseResult = "";
//        try {
//            // 设置聚合条件
//            AggregationBuilder aggr = AggregationBuilders.percentiles("salary_percentiles").field("salary");
//            // 查询源构建器
//            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//            searchSourceBuilder.aggregation(aggr);
//            searchSourceBuilder.size(0);
//            // 创建查询请求对象，将查询条件配置到其中
//            SearchRequest request = new SearchRequest("mydlq-user");
//            request.source(searchSourceBuilder);
//            // 执行请求
//            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//            // 获取响应中的聚合信息
//            Aggregations aggregations = response.getAggregations();
//            // 输出内容
//            if (RestStatus.OK.equals(response.status()) || aggregations != null) {
//                // 转换为 Percentiles 对象
//                ParsedPercentiles aggregation = aggregations.get("salary_percentiles");
//                log.info("-------------------------------------------");
//                log.info("聚合信息:");
//                for (Percentile percentile : aggregation) {
//                    log.info("百分位：{}：{}", percentile.getPercent(), percentile.getValue());
//                }
//                log.info("-------------------------------------------");
//            }
//            // 根据具体业务逻辑返回不同结果，这里为了方便直接将返回响应对象Json串
//            responseResult = response.toString();
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return responseResult;
//    }

}